#include <stdlib.h>
#include <string.h>

#include "CALC_Stack.h"

static int calc_IsStackFull(IN CALC_STACK_S *pstCalcStack)
{
  DBGASSERT(NULL != pstCalcStack);

  return (pstCalcStack->uiItemNum == pstCalcStack->uiItemNumMax);
}

int Calc_StackInit(IN unsigned int uiItemNumMax,
                   OUT CALC_STACK_S *pstCalcStack)
{
  DBGASSERT(NULL != pstCalcStack);

  bzero(pstCalcStack, sizeof(CALC_STACK_S));

  pstCalcStack->pstStack = malloc(uiItemNumMax * sizeof(CALC_ITEM_S));

  if (NULL == pstCalcStack->pstStack) {
    return ERR_FAILED;
  }
  bzero(pstCalcStack->pstStack, uiItemNumMax * sizeof(CALC_ITEM_S));

  pstCalcStack->uiItemNum = 0;
  pstCalcStack->uiItemNumMax = uiItemNumMax;

  return ERR_SUCCESS;
}

int Calc_IsStackEmpty(IN CALC_STACK_S *pstCalcStack)
{
  DBGASSERT(NULL != pstCalcStack);
    
  return (0 == pstCalcStack->uiItemNum);
}

int Calc_StackPush(IN CALC_STACK_S *pstCalcStack,
                   IN CALC_ITEM_S *pstCalcItem)
{
  DBGASSERT(NULL != pstCalcStack);
  DBGASSERT(NULL != pstCalcItem);  
  
  if (calc_IsStackFull(pstCalcStack)) {
    return ERR_FAILED;
  }

  (void)memcpy(&(pstCalcStack->pstStack[pstCalcStack->uiItemNum]),
               pstCalcItem,
               sizeof(CALC_ITEM_S));

  ++pstCalcStack->uiItemNum;

  return ERR_SUCCESS;
}

int Calc_StackPop(IN CALC_STACK_S *pstCalcStack,
                  OUT CALC_ITEM_S *pstCalcItem)
{
  DBGASSERT(NULL != pstCalcStack);
  DBGASSERT(NULL != pstCalcItem);  

  if (Calc_IsStackEmpty(pstCalcStack)) {
    return ERR_FAILED;
  }
  
  --pstCalcStack->uiItemNum;

  (void)memcpy(pstCalcItem,
               &(pstCalcStack->pstStack[pstCalcStack->uiItemNum]),
               sizeof(CALC_ITEM_S));

  return ERR_SUCCESS;
}

void Calc_StackDestroy(IN CALC_STACK_S *pstCalcStack)
{
  if ((NULL != pstCalcStack) &&
      (NULL != pstCalcStack->pstStack)) {
    free(pstCalcStack->pstStack);
  }

  return;
}

unsigned int Calc_StackGetItemCount(IN CALC_STACK_S *pstStack)
{
  DBGASSERT(NULL != pstStack);

  return pstStack->uiItemNum;
}

